package model

import (
	"fileNest/dao"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

type PathItem struct {
	ID   *primitive.ObjectID `bson:"id" json:"id"`
	Name string              `bson:"name" json:"name"`
}

type FileEntry struct {
	ID          *primitive.ObjectID `bson:"_id" json:"id"`
	UserID      string              `bson:"user_id" json:"userId"`
	ParentID    *primitive.ObjectID `bson:"parent_id" json:"parentId"`
	PathList    []PathItem          `bson:"path_list" json:"pathList"`
	Name        string              `bson:"name" json:"name"`
	IsDir       bool                `bson:"is_dir" json:"isDir"`
	StoragePath string              `bson:"storage_path" json:"storagePath"`
	Size        uint64              `bson:"size" json:"size"`
	MimeType    string              `bson:"mime_type" json:"mimeType"`
	IsDel       bool                `bson:"is_del" json:"isDel"`
	DeleteAt    *time.Time          `bson:"delete_at" json:"deleteAt"`
	CreatedAt   *time.Time          `bson:"created_at" json:"createdAt"`
	UpdatedAt   *time.Time          `bson:"updated_at" json:"updatedAt"`
}

type FileEntryList []FileEntry

type FileEntryResult struct {
	FileEntry `bson:",inline"`
	Children  FileEntryResultList `json:"children"`
}

type FileEntryResultList []FileEntryResult

// 转换类型
func (this *FileEntryList) FormatToFileEntryResult() (result FileEntryResultList) {
	for _, k := range *this {
		result = append(result, FileEntryResult{
			FileEntry: k,
			Children:  FileEntryResultList{},
		})
	}
	return
}

// 组装树形结构
// BuildFolderTree 构建文件夹的树形结构（修改原 list 内容）
func (list *FileEntryResultList) BuildFolderTree() {
	idMap := make(map[primitive.ObjectID]*FileEntryResult)

	// 初始化 idMap，同时清空 Children
	for i := range *list {
		node := &(*list)[i]
		node.Children = nil
		if node.ID != nil {
			idMap[*node.ID] = node
		}
	}

	var roots FileEntryResultList

	// 递归函数，构建每个节点的子树
	var build func(node *FileEntryResult)
	build = func(node *FileEntryResult) {
		for _, child := range idMap {
			if child.ParentID != nil && node.ID != nil && *child.ParentID == *node.ID {
				build(child) // 先构建子节点的子树
				node.Children = append(node.Children, *child)
			}
		}
	}

	// 找出根节点，并构建子树
	for _, node := range idMap {
		if node.ParentID == nil {
			build(node)
			roots = append(roots, *node)
		}
	}

	// 将结果赋值回 list
	*list = roots
}

// 递归文件夹下所有文件
func (this FileEntryList) GetFolderRecursively(ids *[]primitive.ObjectID) (err error) {
	for _, v := range this {
		if v.IsDir {
			// 文件夹，再次递归
			*ids = append(*ids, *v.ID)

			var query = bson.M{
				"parent_id": v.ID,
			}
			var result FileEntryList
			if err = dao.DBFindMoreWithOutPage("entries", query, &result); err != nil {
				return
			}
			result.GetFolderRecursively(ids)
		} else {
			// 不是文件夹，直接返回
			*ids = append(*ids, *v.ID)
		}
	}
	return
}
